package com.mentalhealthplatform.global.rbac.service.entity;

import com.mentalhealthplatform.global.rbac.dto.normal.ButtonComponentDTO;
import com.mentalhealthplatform.global.rbac.dto.normal.MenuDTO;
import com.mentalhealthplatform.global.rbac.dto.normal.SimpleEndpointDTO;
import com.mentalhealthplatform.global.rbac.model.Menu;
import com.mentalhealthplatform.global.rbac.model.ButtonComponent;
import com.mentalhealthplatform.global.rbac.model.Endpoint;
import com.mentalhealthplatform.global.rbac.repository.ButtonComponentRepository;
import com.mentalhealthplatform.global.rbac.repository.MenuRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class MenuService {

    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private ButtonComponentRepository buttonComponentRepository;

    public Set<MenuDTO> getMenuHierarchy() {
        // 获取所有菜单
        List<Menu> allMenus = menuRepository.findAll();

        // 构建 MenuDto 层次结构
        return buildMenuHierarchy(allMenus);
    }

    private Set<MenuDTO> buildMenuHierarchy(List<Menu> menus) {
        // 找出顶层菜单（parentMenu为null的菜单）
        Set<Menu> rootMenus = menus.stream()
                .filter(menu -> menu.getParentMenu() == null)
                .collect(Collectors.toSet());

        // 递归构建菜单树的 DTO 结构
        return rootMenus.stream()
                .map(this::convertToMenuDto)
                .collect(Collectors.toSet());
    }

    private MenuDTO convertToMenuDto(Menu menu) {
        MenuDTO menuDto = new MenuDTO();
        menuDto.setId(menu.getId());
        menuDto.setIdentifier(menu.getIdentifier());
        menuDto.setDisplayName(menu.getDisplayName());
        menuDto.setType(menu.getType());
        menuDto.setUrl(menu.getUrl());
        menuDto.setStatus(menu.isStatus());
        menuDto.setVisible(menu.isVisible());
        menuDto.setIcon(menu.getIcon());
        menuDto.setOrderNum(menu.getOrderNum());
        menuDto.setDescription(menu.getDescription());

        // 设置按钮组件 DTO
        Set<ButtonComponent> buttonComponents = buttonComponentRepository.findByParentMenu(menu);

        Set<ButtonComponentDTO> buttonComponentDTOs = buttonComponents.stream()
                .map(this::convertToButtonComponentDto)
                .collect(Collectors.toSet());
        menuDto.setButtonComponents(buttonComponentDTOs);

        // 直接通过 menu.getChildMenus() 获取子菜单
        Set<MenuDTO> childMenuDTOs = menu.getChildMenus().stream()
                .map(this::convertToMenuDto)
                .collect(Collectors.toSet());
        menuDto.setChildMenus(childMenuDTOs);

        return menuDto;
    }

    private ButtonComponentDTO convertToButtonComponentDto(ButtonComponent button) {
        ButtonComponentDTO buttonDto = new ButtonComponentDTO();
        buttonDto.setId(button.getId());
        buttonDto.setIdentifier(button.getIdentifier());
        buttonDto.setDisplayName(button.getDisplayName());
        buttonDto.setDisplayType(button.getDisplayType());
        buttonDto.setDescription(button.getDescription());
        buttonDto.setOrderNum(button.getOrderNum());
        buttonDto.setVisible(button.isVisible());
        buttonDto.setStatus(button.isStatus());

        // 设置端点 DTO
        Set<SimpleEndpointDTO> endpointDtos = button.getEndpoints().stream()
                .map(this::convertToSimpleEndpointDto)
                .collect(Collectors.toSet());
        buttonDto.setEndpoints(endpointDtos);

        return buttonDto;
    }

    private SimpleEndpointDTO convertToSimpleEndpointDto(Endpoint endpoint) {
        SimpleEndpointDTO endpointDto = new SimpleEndpointDTO();
        endpointDto.setId(endpoint.getId());
        endpointDto.setDisplayName(endpoint.getDisplayName());
        endpointDto.setPath(endpoint.getPath());
        endpointDto.setMethod(endpoint.getMethod());

        return endpointDto;
    }

    // 创建菜单
    public MenuDTO createMenu(MenuDTO menuDTO) {
        Menu menu = new Menu(menuDTO.getIdentifier(), menuDTO.getDisplayName(),menuDTO.getType(), menuDTO.getUrl(),
                menuDTO.getIcon(), menuDTO.getOrderNum(), menuDTO.getDescription());

        // 获取父菜单并设置 parentMenu
        if (menuDTO.getParentId() != null){
            Optional<Menu> parentMenu = menuRepository.findById(menuDTO.getParentId());
            if (parentMenu.isPresent()) {
                menu.setParentMenu(parentMenu.get());
            } else {
                throw new IllegalArgumentException("Parent menu not found with ID: " + menuDTO.getParentId());
            }
        }

        Menu savedMenu = menuRepository.save(menu);
        return new MenuDTO(savedMenu);
    }

    // 更新菜单
    public MenuDTO updateMenu(Long id, MenuDTO menuDTO) {
        Optional<Menu> existingMenuOptional = menuRepository.findById(id);
        if (!existingMenuOptional.isPresent()) {
            throw new IllegalArgumentException("菜单不存在");
        }

        Menu existingMenu = existingMenuOptional.get();

        // 更新字段
        existingMenu.setIdentifier(menuDTO.getIdentifier());
        existingMenu.setDisplayName(menuDTO.getDisplayName());
        existingMenu.setType(menuDTO.getType());
        existingMenu.setUrl(menuDTO.getUrl());
        existingMenu.setIcon(menuDTO.getIcon());
        existingMenu.setOrderNum(menuDTO.getOrderNum());
        existingMenu.setDescription(menuDTO.getDescription());
        existingMenu.setStatus(menuDTO.isStatus());
        existingMenu.setVisible(menuDTO.isVisible());

        // 设置 parentMenu
        if (menuDTO.getParentId() != null) {
            // 如果提供了父菜单ID，找到父菜单并设置
            Optional<Menu> parentMenuOptional = menuRepository.findById(menuDTO.getParentId());
            if (parentMenuOptional.isPresent()) {
                existingMenu.setParentMenu(parentMenuOptional.get());
            } else {
                throw new IllegalArgumentException("父菜单不存在");
            }
        } else {
            // 如果没有提供父菜单ID，设置为null，表示根菜单
            existingMenu.setParentMenu(null);
        }

        // 保存更新后的菜单
        Menu updatedMenu = menuRepository.save(existingMenu);

        // 返回更新后的菜单DTO
        return new MenuDTO(updatedMenu);
    }


    // 删除菜单
    public void deleteMenu(Long id) {
        Optional<Menu> menuOptional = menuRepository.findById(id);
        if (!menuOptional.isPresent()) {
            throw new IllegalArgumentException("菜单不存在");
        }

        menuRepository.deleteById(id);
    }

    // 切换菜单状态
    public MenuDTO toggleMenuStatus(Long id) {
        Optional<Menu> menuOptional = menuRepository.findById(id);
        if (!menuOptional.isPresent()) {
            throw new IllegalArgumentException("菜单不存在");
        }

        Menu menu = menuOptional.get();
        menu.toggleStatus();
        Menu updatedMenu = menuRepository.save(menu);
        return new MenuDTO(updatedMenu);
    }

    // 切换菜单可视状态
    public MenuDTO toggleMenuVisibility(Long id) {
        Optional<Menu> menuOptional = menuRepository.findById(id);
        if (!menuOptional.isPresent()) {
            throw new IllegalArgumentException("菜单不存在");
        }

        Menu menu = menuOptional.get();
        menu.setVisible(!menu.isVisible());
        Menu updatedMenu = menuRepository.save(menu);
        return new MenuDTO(updatedMenu);
    }
}
